package org.xteam.sled.semantic;

import org.xteam.sled.ast.DefaultSledVisitor;
import org.xteam.sled.ast.EqOp;
import org.xteam.sled.ast.Equation;
import org.xteam.sled.ast.GeOp;
import org.xteam.sled.ast.GtOp;
import org.xteam.sled.ast.LeOp;
import org.xteam.sled.ast.LtOp;
import org.xteam.sled.ast.NeOp;
import org.xteam.sled.semantic.exp.Exp;
import org.xteam.sled.semantic.exp.ExpCondition;


public class BooleanSemantic extends DefaultSledVisitor {
	// elabBool (A.APP _) = error "expected boolean expression; found constructor application"
	// elabBool (A.IDENT id) = error ("expected boolean expression; found identifier " ^ id)
	// elabBool (A.INT n) = error "expect boolean expression; found integer literal"
	// elabBool (A.LITERAL_exp s) = error "expected boolean expression; found string literal"
	
	// app (A.OR, es)     = error "expected boolean expression; found pattern"
	// app (A.AND, es)    = error "expected boolean expression; found pattern"
	// app (A.CONCAT, es) = error "expected boolean expression; found pattern"
	// app (A.PREFIX_DOTS,  _) = error "expected boolean expression; found pattern"
	// app (A.POSTFIX_DOTS, _) = error "expected boolean expression; found pattern"
	// app (A.SOME_token, es) = error "expected boolean expression; found pattern"
	// app (A.PLABEL l, es)   = error "expected boolean expression; found pattern"
	      
	// app (A.LIST, es)   = error "generating expression in boolean condition"
	// app (A.GEN_to, es) = error "generating expression in boolean condition"

	// app (A.PLUS,  es) = error "expected boolean; found integer expression"
	// app (A.MINUS, es) = error "expected boolean; found integer expression"
	// app (A.TIMES, es) = error "expected boolean; found integer expression"
	// app (A.DIV,   es) = error "expected boolean; found integer expression"
	      
	// app (A.SLICE, es)    = error "expected boolean; found integer expression"
	// app (A.EXTEND, es)   = error "expected boolean; found integer expression"
	// app (A.WILDCARD, es) = error "expected boolean; found integer expression"
	

	private IEvaluationContext context;
	private ExpCondition result;
	private int cond;

	public BooleanSemantic(IEvaluationContext context) {
		this.context = context;
	}
	
	public ExpCondition getExpression() {
		return result;
	}
	
	// app (A.RELOP rel, es) = emap (binapp (fn (l, r) => Exp.condition (l, rel, r))) (elabSingleInts es)
	public void visitEquation(Equation equation) {
		equation.getRelop().visit(this);
		Exp l = new IntegerSemantic(context).analyse(equation.getLeft());
		Exp r = new IntegerSemantic(context).analyse(equation.getRight());
		result = new ExpCondition(cond, l, r);
	}
	
	public void visitEqOp(EqOp eqOp) {
		cond = ExpCondition.EQ;
	}
	
	public void visitNeOp(NeOp neOp) {
		cond = ExpCondition.NE;
	}
	
	public void visitLeOp(LeOp leOp) {
		cond = ExpCondition.LE;
	}
	
	public void visitLtOp(LtOp ltOp) {
		cond = ExpCondition.LT;
	}
	
	public void visitGeOp(GeOp geOp) {
		cond = ExpCondition.GE;
	}
	
	public void visitGtOp(GtOp gtOp) {
		cond = ExpCondition.GT;
	}
	
}
